﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MediaBrowser.Library;
using System.IO;
using MediaBrowser;
using System.Diagnostics;
using System.Management;
using System.Threading;
using System.Runtime.InteropServices;

namespace MBWebService.Core.Classes
{
    public class PlayHelper
    {
        #region Private Members

        private Dictionary<MediaType, ConfigData.ExternalPlayer> configuredPlayers = null;

        #endregion

        public PlayHelper(ConfigData data)
        {
            //data = ConfigData.FromFile(AppSettings.MediaBrowserWsDirectory);
            configuredPlayers = new Dictionary<MediaType, ConfigData.ExternalPlayer>();
            
            if (data.ExternalPlayers != null)
                foreach (var x in data.ExternalPlayers)
                    configuredPlayers[x.MediaType] = x;
        }

        public bool PlayExternalSuccess(MediaCollection collection)
        {
            bool retVal = false;
            if (collection.Count > 0)
            {
                string path = collection.First();
                MediaType type = DetermineType(path);
                if (configuredPlayers.ContainsKey(type))
                {
                    try
                    {
                        ConfigData.ExternalPlayer p = configuredPlayers[type];
                        string args = string.Format(p.Args, path);
                        Process player = Process.Start(p.Command, args);
                        retVal = true;
                        ThreadPool.QueueUserWorkItem(_ =>
                            {
                                Debug.WriteLine("minimizeMCE and then give focus to external player");
                                Process extPlayer = (Process)player;

                                //minimize MCE
                                IntPtr mceWnd = FindWindow(null, "Windows Media Center");
                                WINDOWPLACEMENT wp = new WINDOWPLACEMENT();
                                GetWindowPlacement(mceWnd, ref wp);
                                wp.showCmd = 2; // 1- Normal; 2 - Minimize; 3 - Maximize;
                                SetWindowPlacement(mceWnd, ref wp);

                                ThreadPool.QueueUserWorkItem(new WaitCallback(GiveFocusToExtPlayer), player);
                                extPlayer.WaitForExit();

                                wp.showCmd = 1; // 1- Normal; 2 - Minimize; 3 - Maximize;
                                SetWindowPlacement(mceWnd, ref wp);
                                SetForegroundWindow(mceWnd);
                            });
                    }
                    catch (Exception ex)
                    {
                        Logging.Logger.Instance.LogMessage("Error playing external file: {0}", ex.Message);
                    }
                }
            }

            return retVal;
        }

        private void GiveFocusToExtPlayer(object player)
        {
            //set external player to foreground
            Process extPlayer = (Process)player;
            extPlayer.Refresh();
            extPlayer.WaitForInputIdle(5000); //give the external player 5 secs to show up and then minimize MCE
            SetForegroundWindow(extPlayer.MainWindowHandle);
        }


        public bool IsMcOpen
        {
            get
            {
                return Process.GetProcessesByName("ehshell").Any();
            }
        }

        private static MediaType DetermineType(string path)
        {
            path = path.ToLower();
            if (path.Contains("video_ts"))
                return MediaType.DVD;
            if (path.EndsWith(".avi"))
                return MediaType.Avi;
            if (path.EndsWith(".mpg"))
                return MediaType.Mpg;
            if (path.EndsWith(".mkv"))
                return MediaType.Mkv;
            if (path.EndsWith(".mp4"))
                return MediaType.Mp4;
            if (path.EndsWith(".pls"))
                return MediaType.PlayList;
            if (path.EndsWith(".ts") || path.EndsWith(".m2ts"))
                return MediaType.Ts;
            if (path.Contains("bdmv"))
                return MediaType.BluRay;
            if (path.Contains("hvdvd_ts"))
                return MediaType.HDDVD;
            if (Directory.Exists(Path.Combine(path, "VIDEO_TS")))
                return MediaType.DVD;
            if (Directory.Exists(Path.Combine(path, "BDMV")))
                return MediaType.BluRay;
            if (Directory.Exists(Path.Combine(path, "HVDVD_TS")))
                return MediaType.HDDVD;
            return MediaType.Unknown;
        }

        #region Stuff from MediaBrowser

        //alesbal: begin
        [DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern bool SetWindowPlacement(IntPtr hWnd,
                           ref WINDOWPLACEMENT lpwndpl);
        private struct POINTAPI
        {
            public int x;
            public int y;
        }

        private struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        private struct WINDOWPLACEMENT
        {
            public int length;
            public int flags;
            public int showCmd;
            public POINTAPI ptMinPosition;
            public POINTAPI ptMaxPosition;
            public RECT rcNormalPosition;
        }
        //alesbal: end

        #endregion

    }
}
